/**
 * This class contains unit tests for validating the behavior of Apex classes
 * and triggers.
 */
@isTest
private class TestSilCustomerHelper 
{
 
    static testMethod void TestFindAccountByPhoneNumber() 
    {
        string  phoneNumber0  = '9999-8888-7777';
        string  phoneNumber1  = '666-555-4444';
        string  phoneNumber2  = '333-222-1111';
        
        Account a1 = new Account();
        a1.Name = 'UnitTest';
        a1.Phone = phoneNumber1;
        a1.RecordTypeId = SilCustomerHelper.GetLocalAdvertiserAccountRecordType();
        insert a1;

        Account a2 = new Account();
        a2.Name = 'UnitTest';
        a2.Phone = phoneNumber2;
        a2.RecordTypeId = SilCustomerHelper.GetLocalAdvertiserAccountRecordType();
        insert a2;

        Account a3 = new Account();
        a3.Name = 'UnitTest';
        a3.Phone = phoneNumber2;
        a3.RecordTypeId = SilCustomerHelper.GetLocalAdvertiserAccountRecordType();
        insert a3;
        
        Set<string> pnList = new Set<string>();
        pnList.add(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber0));   // Test zero found
        pnList.add(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber1));  // Test one found
        pnList.add(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber2));  // Test multiple found           

        Test.startTest();
        Map<string, SilCustomerHelper.FindResult> results = SilCustomerHelper.FindAccountByPhoneNumber(pnList);
        Test.stopTest();
        
        System.assertEquals(results.get(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber0)).Count, SilCustomerHelper.ResultCount.None);
        System.assertEquals(results.get(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber1)).Count, SilCustomerHelper.ResultCount.One);
        System.assertEquals(results.get(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber1)).ID, a1.ID);
        System.assertEquals(results.get(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber2)).Count, SilCustomerHelper.ResultCount.Multiple);       
   }

    static testMethod void TestFindContactByPhoneNumber() 
    {
        string  phoneNumber0  = '9999-8888-7777';
        string  phoneNumber1  = '666-555-4444';
        string  phoneNumber2  = '333-222-1111';
        
        Account a1 = new Account();
        a1.Name = 'UnitTest';
        a1.Phone = phoneNumber1;
        a1.RecordTypeId = SilCustomerHelper.GetLocalAdvertiserAccountRecordType();
        insert a1;

        Contact c1 = new Contact();
        c1.LastName = 'UnitTest';
        c1.Phone = phoneNumber1;
        c1.RecordTypeId = SilCustomerHelper.GetLocalAdvertiserContactRecordType();
        c1.AccountId = a1.ID;
        insert c1;

        Account a2 = new Account();
        a2.Name = 'UnitTest';
        a2.Phone = phoneNumber2;
        a2.RecordTypeId = SilCustomerHelper.GetLocalAdvertiserAccountRecordType();
        insert a2;

        Contact c2 = new Contact();
        c2.LastName = 'UnitTest';
        c2.Phone = phoneNumber2;
        c2.RecordTypeId = SilCustomerHelper.GetLocalAdvertiserContactRecordType();
        c2.AccountId = a2.ID;
        insert c2;

        Account a3 = new Account();
        a3.Name = 'UnitTest';
        a3.Phone = phoneNumber2;
        a3.RecordTypeId = SilCustomerHelper.GetLocalAdvertiserAccountRecordType();
        insert a3;
        
        Contact c3 = new Contact();
        c3.LastName = 'UnitTest';
        c3.Phone = phoneNumber2;
        c3.RecordTypeId = SilCustomerHelper.GetLocalAdvertiserContactRecordType();
        c3.AccountId = a3.ID;
        insert c3;

        Set<string> pnList = new Set<string>();
        pnList.add(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber0));   // Test zero found
        pnList.add(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber1));  // Test one found
        pnList.add(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber2));  // Test multiple found           

        Test.startTest();
        Map<string, SilCustomerHelper.FindResult> results = SilCustomerHelper.FindAccountByContactPhoneNumber(pnList);
        Test.stopTest();
        
        System.assertEquals (results.get(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber0)).Count, SilCustomerHelper.ResultCount.None);
        System.assertEquals (results.get(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber1)).Count, SilCustomerHelper.ResultCount.One);
        System.assertEquals (results.get(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber1)).ID, a1.ID);
        System.assertEquals (results.get(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber2)).Count, SilCustomerHelper.ResultCount.Multiple);
        
   }
   
    static testMethod void TestFindAccountByPhoneNumberAndName() 
    {
        string  phoneNumber0  = '999-888-7777';
        string  phoneNumber1  = '666-555-4444';
        string  phoneNumber2  = '333-222-1111';
        string  phoneNumber2bis  = '+1 (333) BAC-1111';
        string  phoneNumber3  = '000-444-8888';

        string name0 = 'Name0';
        string name1 = 'Name1';
        string name2 = 'Name2';
        string name3 = 'Name3';
        string name3bis = 'naME3';
        
        Account a1 = new Account();
        a1.Name =name1;
        a1.Phone = phoneNumber1;
        a1.RecordTypeId = SilCustomerHelper.GetLocalAdvertiserAccountRecordType();
        insert a1;

        Account a2 = new Account();
        a2.Name = name2;
        a2.Phone = phoneNumber2;
        a2.RecordTypeId = SilCustomerHelper.GetLocalAdvertiserAccountRecordType();
        insert a2;

        Account a3 = new Account();
        a3.Name = name3;
        a3.Phone = phoneNumber2;
        a3.RecordTypeId = SilCustomerHelper.GetLocalAdvertiserAccountRecordType();
        insert a3;

        Account a4 = new Account();
        a4.Name = name2;
        a4.Phone = phoneNumber3;
        a4.RecordTypeId = SilCustomerHelper.GetLocalAdvertiserAccountRecordType();
        insert a4;

         Account a5 = new Account();
        a5.Name = name3;
        a5.Phone = phoneNumber3;
        a5.RecordTypeId = SilCustomerHelper.GetLocalAdvertiserAccountRecordType();
        insert a5;

         Account a6 = new Account();
        a6.Name = name3;
        a6.Phone = phoneNumber3;
        a6.RecordTypeId = SilCustomerHelper.GetLocalAdvertiserAccountRecordType();
        insert a6;
        
        Set<string> phoneList = new Set<string>();
        phoneList.add(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber0)); 
        phoneList.add(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber1)); 
        phoneList.add(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber2bis));            
        phoneList.add(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber3));            

        Set<string> nameList = new Set<string>();
        nameList.add(name0);
        nameList.add(name1);
        nameList.add(name2);
        nameList.add(name3bis);
        
        Test.startTest();
        Map<string,Map<string,SilCustomerHelper.FindResult>> results = SilCustomerHelper.FindAccountByPhoneNumberAndName(phoneList, nameList);
        Test.stopTest();
        
        System.assertEquals(results.get(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber0)), null); // Test zero

        System.assertEquals(results.get(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber1)).get(name1.ToUpperCase()).Count, SilCustomerHelper.ResultCount.One); // Test one
        System.assertEquals(results.get(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber1)).get(name1.ToUpperCase()).ID, a1.ID);

        System.assertEquals(results.get(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber2)).get(name3.ToUpperCase()).Count, SilCustomerHelper.ResultCount.One); // Test one
        System.assertEquals(results.get(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber2)).get(name3.ToUpperCase()).ID, a3.ID);
        System.assertEquals(results.get(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber2bis)).get(name3bis.ToUpperCase()).ID, a3.ID);
        
        System.assertEquals(results.get(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber3)).get(name3.ToUpperCase()).Count, SilCustomerHelper.ResultCount.Multiple); // Test multiple       
   }
   
    static testMethod void TestFindAccountByContactPhoneNumberAndAccountName() 
    {
        string  phoneNumber0  = '999-888-7777';
        string  phoneNumber1  = '666-555-4444';
        string  phoneNumber2  = '333-222-1111';
        string  phoneNumber3  = '000-444-8888';
        
        string name0 = 'Name0';
        string name1 = 'Name1';
        string name2 = 'Name2';
        string name3 = 'Name3';
        
        Account a1 = new Account();
        a1.Name =name1;
        a1.RecordTypeId = SilCustomerHelper.GetLocalAdvertiserAccountRecordType();
        insert a1;

        Contact c1 = new Contact();
        c1.LastName =name1;
        c1.Phone = phoneNumber1;
        c1.AccountId = a1.ID;
        c1.RecordTypeId = SilCustomerHelper.GetLocalAdvertiserContactRecordType();
        insert c1;

        Account a2 = new Account();
        a2.Name = name2;
        a2.RecordTypeId = SilCustomerHelper.GetLocalAdvertiserAccountRecordType();
        insert a2;

        Contact c2 = new Contact();
        c2.LastName =name2;
        c2.Phone = phoneNumber2;
        c2.AccountId = a2.ID;
        c2.RecordTypeId = SilCustomerHelper.GetLocalAdvertiserContactRecordType();
        insert c2;

        Account a3 = new Account();
        a3.Name = name3;
        a3.RecordTypeId = SilCustomerHelper.GetLocalAdvertiserAccountRecordType();
        insert a3;

        Contact c3 = new Contact();
        c3.LastName =name3;
        c3.Phone = phoneNumber2;
        c3.AccountId = a3.ID;
        c3.RecordTypeId = SilCustomerHelper.GetLocalAdvertiserContactRecordType();
        insert c3;

        Account a4 = new Account();
        a4.Name = name2;
        a4.RecordTypeId = SilCustomerHelper.GetLocalAdvertiserAccountRecordType();
        insert a4;

        Contact c4 = new Contact();
        c4.LastName =name2;
        c4.Phone = phoneNumber3;
        c4.AccountId = a4.ID;
        c4.RecordTypeId = SilCustomerHelper.GetLocalAdvertiserContactRecordType();
        insert c4;

         Account a5 = new Account();
        a5.Name = name3;
        a5.RecordTypeId = SilCustomerHelper.GetLocalAdvertiserAccountRecordType();
        insert a5;

        Contact c5 = new Contact();
        c5.LastName =name3;
        c5.Phone = phoneNumber3;
        c5.AccountId = a5.ID;
        c5.RecordTypeId = SilCustomerHelper.GetLocalAdvertiserContactRecordType();
        insert c5;

         Account a6 = new Account();
        a6.Name = name3;
        a6.RecordTypeId = SilCustomerHelper.GetLocalAdvertiserAccountRecordType();
        insert a6;
        
        Contact c6 = new Contact();
        c6.LastName =name3;
        c6.Phone = phoneNumber3;
        c6.AccountId = a6.ID;
        c6.RecordTypeId = SilCustomerHelper.GetLocalAdvertiserContactRecordType();
        insert c6;

        Set<string> phoneList = new Set<string>();
        phoneList.add(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber0)); 
        phoneList.add(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber1)); 
        phoneList.add(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber2));            
        phoneList.add(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber3));            

        Set<string> nameList = new Set<string>();
        nameList.add(name0);
        nameList.add(name1);
        nameList.add(name2);
        nameList.add(name3);
        
        Test.startTest();
        Map<string,Map<string,SilCustomerHelper.FindResult>> results = SilCustomerHelper.FindAccountByContactPhoneNumberAndAccountName(phoneList, nameList);
        Test.stopTest();
        
        System.assertEquals(results.get(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber0)), null); // Test zero

        System.assertEquals(results.get(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber1)).get(name1.ToUpperCase()).Count, SilCustomerHelper.ResultCount.One); // Test one
        System.assertEquals(results.get(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber1)).get(name1.ToUpperCase()).ID, a1.ID);

        System.assertEquals(results.get(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber2)).get(name3.ToUpperCase()).Count, SilCustomerHelper.ResultCount.One); // Test one
        System.assertEquals(results.get(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber2)).get(name3.ToUpperCase()).ID, a3.ID);
        
        System.assertEquals(results.get(SilCustomerHelper.CreatePhoneNumberHash(phoneNumber3)).get(name3.ToUpperCase()).Count, SilCustomerHelper.ResultCount.Multiple); // Test multiple       
   }

    static testMethod void TestFindAdvertiserAccountByName() 
    {
        string name0  = 'UNITTEST_0';
        string name1  = 'UNITTEST_1';
        string name2  = 'UNITTEST_2';
                
        Account a1 = new Account();
        a1.Name = name1;
        a1.RecordTypeID =SilCustomerHelper.GetLocalAdvertiserAccountRecordType();
        insert a1;

        Account a2 = new Account();
        a2.Name = name2;
        a2.RecordTypeID =SilCustomerHelper.GetLocalAdvertiserAccountRecordType();
        insert a2;

        Account a3 = new Account();
        a3.Name = name2;
        a3.RecordTypeID =SilCustomerHelper.GetLocalAdvertiserAccountRecordType();
        insert a3;

        Account a4 = new Account();
        a4.Name = name1;
        a4.RecordTypeID = RecordTypeHelper.GetRecordTypeID('Account', 'Internal Account');
        insert a4;

        Set<string> nameSet = new Set<string>();
        nameSet.add(name0); // Find zero
        nameSet.add(name1); // Find one
        nameSet.add(name2); // Find multiple
        
        Test.startTest();
        Map<string, SilCustomerHelper.FindResult> results = SilCustomerHelper.FindAdvertiserAccountByName(nameSet); 
        Test.stopTest();

        System.assertEquals(results.get(name0.ToUpperCase()).Count, SilCustomerHelper.ResultCount.None);
        System.assertEquals(results.get(name1.ToUpperCase()).Count, SilCustomerHelper.ResultCount.One);
        System.assertEquals(results.get(name1.ToUpperCase()).ID, a1.ID);
        System.assertEquals(results.get(name2.ToUpperCase()).Count, SilCustomerHelper.ResultCount.Multiple);
   }
   
    static testMethod void TestFindAccountByAFrontierCustomerId() 
    {
        string name = 'UNITTEST_83298';
        
        string afCustomerID0 = '111222333';
        string afCustomerID1 = '999888777';
        
        Account a1 = new Account();
        a1.Name = name;
        a1.AFrontier_CustomerID__c = afCustomerID1;
        a1.RecordTypeId = SilCustomerHelper.GetLocalAdvertiserAccountRecordType();
        insert a1;
        
        Set<string> setAFIDs = new Set<string>();
        setAFIDs.Add(afCustomerID0); // Zero found
        setAFIDs.Add(afCustomerID1); // One  found
        
        Test.startTest();
        Map<string, SilCustomerHelper.FindResult> results = SilCustomerHelper.FindAccountByAFrontierCustomerId(setAFIDs);
        Test.stopTest();

        System.assertEquals (results.get(afCustomerID0.ToUpperCase()).Count, SilCustomerHelper.ResultCount.None);
        System.assertEquals (results.get(afCustomerID1.ToUpperCase()).Count, SilCustomerHelper.ResultCount.One);
        System.assertEquals (results.get(afCustomerID1.ToUpperCase()).ID, a1.ID);
   }
   
    class ComparePhone
    {
        public string Phone1;
        public string Phone2;
        public boolean IsMatch;
        public ComparePhone(string phone1, string phone2, boolean isMatch)
        {
            this.Phone1 = phone1;
            this.Phone2 = phone2;
            this.IsMatch = isMatch;
        }
    } 
    
   static testMethod void TestCreatePhoneNumberHash()
   {
        
        string hash1;
        string hash2;
        List<ComparePhone> numbers = new List<ComparePhone>();
        
        numbers.add(new ComparePhone('(702) 454-0505', '1 702 454 0505', true));
        numbers.add(new ComparePhone('(212) 259-5286', '1 212 259-5286', true));
        numbers.add(new ComparePhone('+1 404-924 7755', '(404) 924-7755', true));
        numbers.add(new ComparePhone('1323 370-8065', '(323) 370-8065', true));
        numbers.add(new ComparePhone('617-584-ZZZZ', '(617) 584-9999', true));          
        numbers.add(new ComparePhone('212/907.7055', '1 (212) 90 77 05 5', true));          
        numbers.add(new ComparePhone('804/698/8572', '+1 804 698-8572', true));         
        numbers.add(new ComparePhone('(215) 545-4850 Ext 106', '1 215 545-4850 x106', true));       
        numbers.add(new ComparePhone('P: 800.235.9918 x3280 + Cell', '1 800-235-9918 extension 3280', true));       
        numbers.add(new ComparePhone('tel 416 263 6300 x 3104', '+1 (416) 263-6300 (3104)', true));         
        numbers.add(new ComparePhone('(267) 765-7622 F', '+1 (267) 765-7622', true));       
        numbers.add(new ComparePhone('+44 (0)7708 329069', '44 07 70 83 29 069', true));
        numbers.add(new ComparePhone('1 800 ADG-JMPT', '1 800 BEH-KNQU', true));
        numbers.add(new ComparePhone('1 800 CFI-LORU', '1 800 234-5678', true));
        
        numbers.add(new ComparePhone('34 91 131 17 91', '+34 9 11 31 17 91', true));
        numbers.add(new ComparePhone('Unknown', '', true));
        numbers.add(new ComparePhone('Media Planner', '', true));
        numbers.add(new ComparePhone('800-543', '', true));

        numbers.add(new ComparePhone('(415) 393-9271', '(415) 393-9272', false));

        // Expected to fail, would be nice if they worked
        //numbers.add(new ComparePhone('+44 (0)7708 329069', '+44 7708 329069', true));
        //numbers.add(new ComparePhone('404 Park Avenue 11th Floor', '', true));        

        
        Test.startTest();
        
        for(integer i=0; i < numbers.size(); i++)
        {
            hash1 = SilCustomerHelper.CreatePhoneNumberHash(numbers[i].Phone1);
            hash2 = SilCustomerHelper.CreatePhoneNumberHash(numbers[i].Phone2);
            
            System.Debug('Phone Number ' + i + ' Hash 1 [' + hash1 + '] Hash 2 [' + hash2 + ']');
            
            if(numbers[i].IsMatch)
                System.assert((hash1 == hash2 && numbers[i].IsMatch) || (hash1 != hash2 && !numbers[i].IsMatch), 'Phone Number ' + i + ' Hash 1 [' + hash1 + '] Hash 2 [' + hash2 + '] Match Expected:' + numbers[i].IsMatch);           
        }
        
        Test.stopTest();            
   }
   
 }